package com.sec.etech.ism.service.impl;

import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson.JSONObject;
import com.sec.etech.ism.model.IsmAppSetting;
import com.sec.etech.ism.model.IsmServiceDef;
import com.sec.etech.ism.service.*;
import com.sec.etech.ism.util.SapSignatureUtil;
import lombok.extern.slf4j.Slf4j;
import org.openbpm.base.core.util.StringUtil;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Slf4j
@Service
public class IsmUpdateComponentMaterialNoServiceImpl implements IsmMethodService {
    @Resource
    JdbcTemplate jdbcTemplate;
    @Resource
    IsmAppSettingService ismAppSettingService;
    @Resource
    IsmTaskService ismTaskService;
    @Resource
    IsmServiceDefService ismServiceDefService;
    @Resource
    IsmTaskLogService ismTaskLogService;
    @Resource
    MaterialNoLogService materialNoLogService;
    @Resource
    IsmCommonService ismCommonService;

    @Override
    public JSONObject call(String sysCode, String serviceCode, JSONObject businessParams) throws Exception{
        JSONObject result = new JSONObject();
        String msg = this.updateComponentMaterialNo(sysCode, serviceCode, businessParams);
        result.put("flag", msg);
        result.put("msg", msg);
        return result;
    }

    /**
     * 调用SAP接口批量更新零件/毛坯物料号
     * @param sysCode
     * @param serviceCode
     * @param busObj
     * @return
     */
    private String updateComponentMaterialNo(String sysCode, String serviceCode, JSONObject busObj) {
        Map<String, String> logMap = new HashMap<>(5);
        //服务信息
        IsmServiceDef serviceDef = ismServiceDefService.getByCode(serviceCode);
        try{
            //调用的应用信息
            IsmAppSetting appSetting = ismAppSettingService.getByCode(sysCode);
            String url = ismCommonService.getSapPreUrl(appSetting.getAppAddress(), appSetting.getAppConfig()) + "/ZBAPI_MATERIAL_SAVEDATA_LIST";
            //Integer busType = busObj.getInteger("busType");//1-部套
            String sql = "select componentid,componentnum,componentname,component_SAPnum from prod_component " +
                    "where component_SAPnum is not null and component_SAPnum!='' and componentid=?";
            List<Map<String, Object>> comList = jdbcTemplate.queryForList(sql, busObj.getString("componentid"));
            if(comList==null || comList.size()==0) {
                return "请检查部套物料号！";
            }
            JSONObject sapParams = new JSONObject();
            List<JSONObject> zHeadList = new ArrayList<>();
            List<JSONObject> zPlantList = new ArrayList<>();
            List<JSONObject> zPlantXList = new ArrayList<>();
            List<JSONObject> zMDList = new ArrayList<>();
            Map<String, Map<String, Object>> sapNumMap = new HashMap<>();//兼容批量操作

            String sAPNum = comList.get(0).get("component_SAPnum").toString();
            sapNumMap.put(sAPNum, comList.get(0));
            JSONObject zHeadObj = new JSONObject(2);
            zHeadObj.put("MATERIAL", sAPNum);//物料号
            zHeadObj.put("STORAGE_VIEW", "X");
            zHeadList.add(zHeadObj);

            JSONObject zPlantObj = new JSONObject(2);
            zPlantObj.put("MATERIAL", sAPNum);//物料号
            zPlantObj.put("PLANT", "1303");
            zPlantList.add(zPlantObj);

            JSONObject zPlantXObj = new JSONObject(2);
            zPlantXObj.put("MATERIAL", sAPNum);//物料号
            zPlantXObj.put("PLANT", "1303");
            zPlantXList.add(zPlantXObj);

            JSONObject zMDObj = new JSONObject();
            zMDObj.put("MATERIAL", sAPNum);//物料号
            zMDObj.put("LANGU_ISO", "ZH");
            zMDObj.put("MATL_DESC", comList.get(0).get("componentnum").toString() + " " +
                    comList.get(0).get("componentname").toString());
            zMDList.add(zMDObj);


            comList.clear();
            sapParams.put("ZHEADDATA", zHeadList);
            sapParams.put("ZPLANTDATA", zPlantList);
            sapParams.put("ZPLANTDATAX", zPlantXList);
            sapParams.put("ZMATERIALDESCRIPTION", zMDList);
            JSONObject dataObj = this.checkSapResult(url, sapParams, serviceDef, appSetting.getAppKey2(),
                    null, busObj.toJSONString(), sysCode, "ZBAPI_MATERIAL_SAVEDATA_LIST", logMap);
            sapParams.clear();
            Map<String, String> sapReturnMap = new HashMap<>();
            if(dataObj!=null && dataObj.containsKey("RETURNS")){
                List<JSONObject> returnList = (List<JSONObject>) dataObj.get("RETURNS");
                if(returnList!=null && returnList.size()>0) {
                    for(JSONObject object : returnList){
                        String type = object.getString("TYPE");
                        String materialNo = object.getString("ID");
                        sapReturnMap.put(materialNo, type);
                    }
                }
            }
            for(Map.Entry<String, Map<String, Object>> entry:sapNumMap.entrySet()){
                String materialNo = entry.getKey();
                String type = sapReturnMap.get(materialNo);
                Integer result = null;
                if(StringUtil.isEmpty(type) && !"E".equals(type) && !"A".equals(type)) {
                    result = 1;
                }else {
                    result = 0;
                }
                Map<String, Object> busMap = entry.getValue();
                //保存或者更新物料号记录表
                materialNoLogService.saveOrUpdateByUpdate(Long.parseLong(busMap.get("componentid").toString()), 1,
                        busObj.toJSONString(), materialNo, result, busMap.get("componentnum").toString(), busMap.get("componentname").toString());
            }
            if(dataObj==null){
                return "更新部套物料号接口异常，请联系管理员处理！";
            }else if(StringUtil.isEmpty(dataObj.getString("message"))){
                return "success";
            }else {
                return dataObj.getString("message");
            }
        }catch (Exception e){
            e.printStackTrace();
            log.error("更新部套物料号接口异常。serviceDef.getCode()={}，serviceDef.getName()={}，logMap={}",
                    serviceDef.getCode(), serviceDef.getName(), logMap);
            return "更新部套物料号接口异常，请联系管理员处理！";
        }
    }


    //检查sap返回结果，获取返回数据
    private JSONObject checkSapResult(String url, JSONObject sapParams, IsmServiceDef serviceDef, String appKey, String businessCode,
                                      String businessParams, String sysCode, String methodName, Map<String, String> logMap) throws Exception{

        JSONObject bodyObj = SapSignatureUtil.buildRequestParams(sapParams, appKey);
        String body = JSONObject.toJSONString(bodyObj);
        int timeout = JSONObject.parseObject(serviceDef.getParams()).getInteger("timeout");
        long startTime = System.currentTimeMillis();
        String result = HttpUtil.post(url, body, timeout*60*1000);
        log.info("SAP系统{}接口耗时：{}ms。", methodName, System.currentTimeMillis() - startTime);
        JSONObject resultObj = JSONObject.parseObject(result);

        JSONObject taskObj = new JSONObject();
        taskObj.put("sysCode", sysCode);
        taskObj.put("serviceCode", serviceDef.getCode());
        taskObj.put("methodName", methodName);
        taskObj.put("businessCode", businessCode);
        taskObj.put("businessParams", businessParams);
        taskObj.put("resultObj", resultObj);
        Long taskId = ismTaskService.checkAndSave(taskObj);
        //保存接口调用日志
        JSONObject logObj = new JSONObject();
        logObj.put("task_id", taskId);
        logObj.put("service_code", serviceDef.getCode());
        logObj.put("service_name", serviceDef.getName());
        logObj.put("method_name", methodName);
        logObj.put("request_url", url);
        logObj.put("input_json", bodyObj);
        logObj.put("output_json", result);
        JSONObject dataObj = resultObj!=null ? resultObj.getJSONObject("data") : null;
        String message = null;
        if(resultObj==null || !resultObj.getBoolean("success")) {
            message = resultObj!=null ? resultObj.getString("message") : "接口无返回数据，请检查接口和网络！";
        }else if(dataObj!=null && StringUtil.isNotEmpty(dataObj.getString("RETURN"))) {
            message = dataObj.getJSONObject("RETURN").getString("MESSAGE");
        }else if(dataObj!=null && StringUtil.isNotEmpty(dataObj.getString("RET"))) {
            message = dataObj.getJSONObject("RET").getString("MESSAGE");
        }
        if(taskId!=null && taskId>0) {
            message = StringUtil.isNotEmpty(message) ? message : "接口返回数据需要人工检查和处理！";
            logObj.put("message", message);
        }
        logMap.put("input", body);
        logMap.put("output", result);
        ismTaskLogService.saveLog(logObj);
        if(dataObj!=null) {
            dataObj.put("message", message);
        }
        return dataObj;
    }

    @Override
    public String methodName(){
        return "updateComponentMaterialNo";
    }

}
